function [cfg,exvars,depvars,indepvars] = DefineParameters(cfg,gui)
%% Variables for the interface
% Definitions for the moddel settings, these settings will overwrite any
% setting defined in the GUI.
cfg.LiveMinimizeVisuals          = {cfg.LiveMinimationVisual*100, 1:35}; % Visualize the minimization procedure: {0, ...} for none
if cfg. AllRegions
cfg.CalculatedRegions       = 1:27; % Model only this subset of regions
end
%% Define parameters used by all models
    % Required parameters for the conversions etc.
    cfg.startdate           = gui.cfg.startdate; % Starting date, names the savefolder
    cfg.DaysPerYear         = 365;      % days/yr
    cfg.HoursPerDay         = 24;       % hr/day
    cfg.HoursPerYear        = cfg.DaysPerYear*cfg.HoursPerDay; %hours/yr
    cfg.MinutesPerHour      = 60;       % min/hr
    cfg.CalibrationTime     = 1:35;     % Number of years with historic data
    cfg.TotalTime           = 1:130;    % Total number of years avialable
    
    cfg.Regions             = 1:27;     % Region
    cfg.Modes               = 1:7;      % Mode
    cfg.Vehicles            = 1;        % Vehicle (depends on mode)
    cfg.Fuels               = 1;        % Fuel (depends on vehicle)
    cfg.ModesFasterThanLDV  = 5:7;      % Modes that are faster than cars
    
    if   cfg.FutureProjection == 1;cfg.Time     = cfg.TotalTime;   % Time
    else cfg.Time     = cfg.CalibrationTime;  end    
    % Load default ModeSet and regionset, can be changed by using
    cfg.TModeSet            = cfg.ModeSet; % Save the menu setting
    cfg.ModeSet             = 'modes7';     % data is by default in this
    cfg.modes               = {'walk','bike','bus','train','car','hs-train','air'};
    
    cfg.TRegionSet          = cfg.RegionSet; % Save the menu setting
    cfg.RegionSet           = 'regions26';
    cfg.allregions          = {'Canada','USA','Mexico','Rest Central America','Brazil','Rest South America' ...
                            ,'Northern Africa','Western Africa','Eastern Africa','South Africa','OECD Europe' ...
                            ,'Eastern Europe','Turkey','Ukraine +','Asia-Stan','Russia +','Middle East' ...
                            ,'India','Korea','China +','South East Asia','Indonesia +','Japan','Oceania' ...
                            ,'Rest of S. Asia','Rest of S. Africa', 'World'};
    cfg.plotinfo            = cell(1, length(cfg.Regions)); % Will be displayed with the plot (in the little box)
    cfg.plotinfo(:)         = {' '};
    cfg.years               = 1971:2100; % Range of years
    cfg.MinOptions          = optimset(optimset('fminsearch'),'MaxFunEvals',50000,'MaxIter',50000,'Algorithm','active-set'); % Used for the minimization function
    cfg.outputfolder        = ['Output/' cfg.OutputFolder '/']; % Name of the folder the output gets put into
    cfg.GAevals             = ones([length(cfg.Regions) cfg.NoRuns]);

    
    %% Load datasets nad transform into the right space
    load(['Data\' cfg.Dataset]); % Source files are XLS documents
    
    [cfg,exvars,~,~,cfg.Modes]   = TransformModesandRegions(cfg,exvars,[],[],cfg.TModeSet);
    [cfg,exvars,~,~,cfg.Regions] = TransformModesandRegions(cfg,exvars,[],[],cfg.TRegionSet);

    %% Reserve memory for variables
    % Dependant variables i.e. variables that are influenced by eachother inside the model
    depvars.ObjectiveFunction       = zeros(length(cfg.Regions));
    depvars.TravelDemand            = zeros([length(cfg.Regions),length(cfg.Time),length(cfg.Modes)]); % p km
    depvars.ModeSplit               = zeros([length(cfg.Regions),length(cfg.Time),length(cfg.Modes)]); % unitless
    depvars.ModeSplitOptimum        = zeros([length(cfg.Regions),length(cfg.Time),length(cfg.Modes)]); % unitless
    depvars.ObjectiveFunction       = ones(length(cfg.Regions),length(cfg.Time)); % unitless
    depvars.PreferenceFactor        = zeros([length(cfg.Regions),length(cfg.Time),length(cfg.Modes)]); % unitless
    depvars.Resid                   = zeros(length(cfg.Regions),length(cfg.Time)); % Residuals
    depvars.ModeWeight              = zeros([length(cfg.Regions),length(cfg.Time),length(cfg.Modes)]); % Used to weight the residuals for a better fit
    
    depvars.errors.TTBfit           = zeros([length(cfg.Regions),1]); % Normalized mean square error over TTB
    depvars.errors.TDfit            = zeros([length(cfg.Regions),1]); % Normalized mean square error over TravelDemand
    depvars.errors.ModeFit          = zeros([length(cfg.Regions),1]); % Normalized mean square error over Modesplit fit
    depvars.errors.OFfit            = zeros([length(cfg.Regions),1]); % Normalized mean square error over Objective Function
    depvars.errors.TMBfit           = zeros([length(cfg.Regions),1]); % Normalized mean square error over Objective Function

    % Independant variables
    indepvars.UseModes              = exvars.TravelDemand(:,35,:)~=0; % Dump HS trains for regions that don't use it
    if cfg.NoUnMotorized || strcmp(cfg.Model,'ModelPoles');    if length(cfg.modes)==4;        indepvars.UseModes(:,:,strcmp(cfg.modes,'NM')) = false;    else;       indepvars.UseModes(:,:,strcmp(cfg.modes,'Walk')|strcmp(cfg.modes,'Bike')) = false;    end;end
    indepvars.TTB                   = ones([length(cfg.Regions),length(cfg.Time)])*1.2*365; % hr/yr, seems to fit the data better than increasing with time
    indepvars.MinTimeWeight         = ones([length(cfg.Regions),1])*0.1*cfg.RestrictTWRange; 
  
switch cfg.Model
    case {'ModelTravelOptimizedTW','ModelTravelLinearTW'}
        %% TIMER input parameters
        % dependant variables
        depvars.TMB                     = zeros([length(cfg.Regions),length(cfg.Time)]); % Percentage of Income
        depvars.RelativeModeCostTravel  = zeros([length(cfg.Regions),length(cfg.Time),length(cfg.Modes)]); % Unitless
        depvars.TimeWeight              = ones(length(cfg.Regions),length(cfg.Time)); % unitless
        
        % independant variables 
        indepvars.PFSaturation              = ones([length(cfg.Regions),1]).*10;
        indepvars.ComfElasticity            = ones([length(cfg.Regions),1]).*0.5;
        indepvars.TimeWeightRuns            = 1; % number of time timeweight should be determined per model model iteration (1/year)
        indepvars.InvInertia                = 1; % Inverse intertia (1 for none)
        indepvars.TMBAdded                  = zeros([length(cfg.Regions),1]);
        indepvars.Lambda                    = ones([length(cfg.Regions),1])*3.2; % unitless modespread
        indepvars.PreferenceFactorStart     = ones([length(cfg.Regions),1,length(cfg.Modes)]).*5; % No unit
        indepvars.PreferenceFactorStart     = (indepvars.PreferenceFactorStart  .* exvars.TravelDemand(:,1,:) ~= 0).* 1; % No unit
        indepvars.PreferenceFactorSlope     = zeros([length(cfg.Regions),1,length(cfg.Modes)]);
        indepvars.PreferenceFactor          = repmat(indepvars.PreferenceFactorStart, [1 length(cfg.Time) 1]) + repmat(cfg.Time,size(indepvars.PreferenceFactorStart)) .* repmat(indepvars.PreferenceFactorSlope,[1 length(cfg.Time) 1]);
        indepvars.InfrastructureLifeTime    = ones([ length(cfg.Regions) 1 length(cfg.Modes)]); % yr
        indepvars.TimeWeight                = ones(length(cfg.Regions),1); % Starting value of TimeWeight
        indepvars.Inertia                   = 1./indepvars.InfrastructureLifeTime; % yr^-1
        indepvars.TravelPrice               = exvars.TravelPrice;

    case {'ModelPoles'}
%% Input parameters POLES
%         indepvars.UseModes              = logical(repmat(permute([0 0 0 1], [1 3 2]),[length(cfg.Regions),1,1]));
        
        % dependant variables
        depvars.EquipmentRate           =  zeros([length(cfg.Regions),length(cfg.Time),length(cfg.Modes)]); % Vehicles / Capita
        depvars.VTravelDemand           =  zeros([length(cfg.Regions),length(cfg.Time),length(cfg.Modes)]); % vkm/yr
        depvars.IncomeElasticityER      =  ones([length(cfg.Regions),length(cfg.Time),length(cfg.Modes)]); % unitless
        depvars.IncomeElasticity        =  ones([length(cfg.Regions),length(cfg.Time),length(cfg.Modes)]); % unitless
                
        % independant variables
        indepvars.IncomeElasticityER    =  1.0*ones([length(cfg.Regions),1,1]); % unitless
        indepvars.TimeTrend             =  repmat(permute([0 0 0.05 0], [1 3 2]),[length(cfg.Regions),1,1]); % unitless
        indepvars.PriceElasticity       =  repmat(permute([0 0.3 0.4 0.8], [1 3 2]),[length(cfg.Regions),1,1]); % unitless
        indepvars.IncomeElasticity      =  repmat(permute([0 1 1 2.2], [1 3 2]),[length(cfg.Regions),1,1]); % unitless
        indepvars.Saturation            =  repmat(permute([Inf Inf Inf 240000], [1 3 2]),[length(cfg.Regions),1,1]); % pkm/yr based on schafer
        indepvars.Saturation(:,1,4)     =  exvars.Saturation(:,1);

    case {'ModelSimple'}
%% Input parameter simplified elasticities
        indepvars.PriceElasticity       = repmat(permute([0.5 0.4 0.8 0.75], [1 3 2]),[length(cfg.Regions),1,1]);  % As defined by Schafer - made negative in the model
        indepvars.IncomeElasticity      = repmat(permute([0.2 1.0 1.2 1.3], [1 3 2]),[length(cfg.Regions),1,1]);   % From the GCAM publication
             
    case {'ModelGcam'}
%% GCAM input parameters
        % Dependant variables
        depvars.ModeCostGcam            = zeros([length(cfg.Regions),length(cfg.Time),length(cfg.Modes)]); % USD/p/km
        indepvars.SWSaturation          = ones([length(cfg.Regions),1]).*35;
        % Independant Variables
        exvars.EnergyCost(exvars.EnergyCost<0) =0;
        indepvars.TravelPrice = ( exvars.NonEnergyCost(:,1:130,:) ...
            .*((repmat(exvars.Income(:,:,:), [1 1 size(depvars.TravelDemand,3)])...
            ./repmat(exvars.Income(:,35,:), [1 130 size(depvars.TravelDemand,3)]))...
            .^-0.5) + exvars.EnergyCost(:,:,:)) ./ exvars.LoadFactor(:,:,:);
        indepvars.CostDistrParameter        = ones([length(cfg.Regions) 1])*2; % unitless modespread - made negative in model
        indepvars.PriceElasticity           = ones([length(cfg.Regions) 1])*1; % As defined by Schafer - made negative in the model
        indepvars.IncomeElasticity          = ones([length(cfg.Regions) 1])*1;   % From the GCAM publication
        indepvars.ShareWeight               = ones([length(cfg.Regions),1,length(cfg.Modes)]); % No unit
        indepvars.ShareWeight               = indepvars.ShareWeight .* (exvars.TravelDemand(:,1,:) ~= 0); % No unit
        indepvars.Sigma                     = zeros([length(cfg.Regions),1]); % Calibration parameter for Gcam
    case {'unlikely'}
%% Unused parameters
        % Dependant variables
        depvars.VehicleSplit            = 0; % unitless
        depvars.NonEnergyCost           = 0; % $/pkm
        depvars.LoadFactor              = 0; % p/vehicle
        depvars.EnergyEfficiency        = 0; % MJ/pkm
        depvars.ComfortFactor           = 0; % unitless
        depvars.DiscountRate            = 0; % unitless
        depvars.NetPresentValue         = 0; % unitless

        % Independant variables
        indepvars.ComfortElasticity         = 0.5; % unitless
        indepvars.ModeLifeTime              = [0 0 20 20 10 25 25]; % yr
        indepvars.Subsidy                   = 0;
end

%% Other variables
        exvars.ModeSplit             = zeros(size(exvars.TravelDemand));
        exvars.ModeSplit(:,:,indepvars.UseModes(1,:)) = exvars.TravelDemand(:,:,indepvars.UseModes(1,:))...
            ./ repmat(sum(exvars.TravelDemand(:,:,indepvars.UseModes(1,:)),3),[1,1,sum(indepvars.UseModes(1,:))]); % Needs to be based on data later one! $ / hr

        
end
